import { isEmpty, isExist, notExist, to, typeOf } from "wsp-toolkit";
import md5 from "md5";
import { message } from "antd";

export function treeMap(
  treeData,
  fn,
  { level = 0, parent = null, beforeFn } = {},
) {
  return treeData
    .map((x, i) => {
      const data = beforeFn?.(x, parent, i, level) ?? x;
      let children;
      if (Array.isArray(data.children)) {
        children = treeMap(data.children, fn, {
          level: level + 1,
          parent: data,
          beforeFn,
        });
      }
      const result = fn({ ...data, children }, parent, i, level);
      if (notExist(result)) {
        return result;
      }

      if (notExist(result.children)) {
        const isShowMenu = data.meta?.isShowMenu;
        if(isShowMenu == false) return null;
        result.children =  Array.isArray(children) && children.length === 0 ? void 0 : children;
      }
      return result;
    })
    .filter((x) => isExist(x));
}

export function encrypt(raw) {
  // return CryptoJS.DES.encrypt(raw, keyHex, config).toString();
  return md5(raw).toString();
}

/**
 * @description Flatten the menu using recursion for easier addition of dynamic routes.
 * @param {Array} menuList - The menu list.
 * @returns {Array}
 */
export function getFlatMenuList(menuList) {
  let newMenuList = JSON.parse(JSON.stringify(menuList));
  return newMenuList.flatMap((item) => [
    item,
    ...(item.children ? getFlatMenuList(item.children) : []),
  ]);
}

/**
 * @description Use recursion to filter out the menu items that need to be rendered in the left menu (excluding menus with isHide == true).
 * @param {Array} menuList - The menu list.
 * @returns {Array}
 */
export function getShowMenuList(getShowMenuList) {
  let newMenuList = JSON.parse(JSON.stringify(menuList));
  return newMenuList.filter((item) => {
    item.children?.length && (item.children = getShowMenuList(item.children));
    return !item.meta?.isHide;
  });
}

class NhMessage {
  static TIME_OUT = 1000;

  errorMsgTimeMap = {};
  timerId;

  error(msg) {
    if (isEmpty(msg) || notExist(msg)) return;
    if (typeof msg === "object") {
      const key = ["message", "errMessage", "errMsg"].find((k) => {
        return typeof msg[k] === "string";
      });
      msg = msg[key] || JSON.stringify(msg);
    }
    if (typeof msg === "string") {
      msg = msg.trim();
    }
    clearTimeout(this.timerId);
    const now = Date.now();
    const recordTime = this.errorMsgTimeMap[msg];
    if (recordTime && now - recordTime < NhMessage.TIME_OUT) return;
    this.errorMsgTimeMap[msg] = now;
    this.timerId = setTimeout(() => {
      this.errorMsgTimeMap = {};
    }, NhMessage.TIME_OUT);
    message.error(msg);
  }
}

export const msg = new NhMessage();

export function checkResSuccess(res) {
  if (res.success !== true) {
    msg.error(`${res.errCode}: ${res.errMessage}`);
    return [false, null];
  }
  return [true, res.data];
}

export async function processReq(reqPromise) {
  const [err, res] = await to(reqPromise);
  if (err) {
    return [err, null];
  }
  if (typeOf(res) !== "Object") {
    return ["响应格式不正确", null];
  }
  if (res.success !== true) {
    return [`${res.errMessage}`, null]; /* ${res.errCode}: */
  }
  return [null, res.data];
}
